package com.example.shardingjdbc.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.shardingjdbc.entity.ScadaHistory;
import com.example.shardingjdbc.inputDto.EnergyConsumptionInquiryDeptSearchInputDto;
import com.example.shardingjdbc.inputDto.HistoryDataSearchInputDto;
import com.example.shardingjdbc.mapper.EnergyConsumptionInquiryDao;
import com.example.shardingjdbc.mapper.HistoryDataDao;
import com.example.shardingjdbc.mapper.ScadaHisthoyMapper;
import com.example.shardingjdbc.model.inputDto.CockpitStatisticalAnalysisInputDto;
import com.example.shardingjdbc.outputDto.EnergyConsumptionInquiryDeptSearchOutputDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 驾驶舱-统计分析
 *
 * @author muhf
 * @date 2024/9/2 10:25
 */
@RestController
@RequestMapping("cockpit")
public class CockpitStatisticalAnalysisController {

    @Autowired
    private ScadaHisthoyMapper scadaHisthoyMapper;

    @Autowired
    private HistoryDataDao historyDataDao;

    @Autowired
    private EnergyConsumptionInquiryDao energyConsumptionInquiryDao;


    @GetMapping("testDual")
    public Object testDual() {
        String result = scadaHisthoyMapper.getMobileFuncChilds(100873540990926859L);
        return result;
    }




    /**
     * 运行监测
     *
     * @param inputDto
     * @return
     * @author muhf
     * @date 2024/9/2 15:26
     */
    @PostMapping("getOperationMonitor")
    public ResultData getOperationMonitor(@RequestBody CockpitStatisticalAnalysisInputDto inputDto) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 设置最大最小日期范围
        Date minDate = sdf.parse("2021-01-01 00:00:00");
        Date maxDate = sdf.parse("2025-12-31 23:59:59");
        // 获取时间戳（毫秒）
        long minTime = minDate.getTime();
        long maxTime = maxDate.getTime();
        // 创建 Random 实例
        Random random = new Random();
        // 随机生成开始时间
        long startTime = minTime + (long) (random.nextDouble() * (maxTime - minTime));
        Date startDate = new Date(startTime);
        // 随机生成结束时间（必须 >= startDate）
        long remainingTime = maxTime - startTime;
        long endTime = startTime + (long) (random.nextDouble() * remainingTime);
        Date endDate = new Date(endTime);


        // 随机生成 heatUnitId（10001 ~ 13000）
        int min = 10001;
        int max = 13000;
        // heat_net_id  随机吧 10001-13000
        String heatUnitId = String.valueOf(new Random().nextInt(max - min + 1) + min);
        System.out.println("查询条件：heatUnitId,startDate,endDate," + heatUnitId + "," + startDate + "," + endDate);
        List<String> heatUnitIdList = new ArrayList<>();
        heatUnitIdList = Arrays.asList(heatUnitId.split(","));
        List<ScadaHistory> scadaHistories = scadaHisthoyMapper.getUnitHistoryDataList(heatUnitIdList, startDate, endDate, "100000000");

        ResultData result = new ResultData();
        result.setStartDate(startDate);
        result.setEndDate(endDate);
        result.setHeatUnitId(heatUnitId);
        result.setData(scadaHistories);
        result.setTotal(scadaHistories.size());
        return result;
    }

    /**
     * 运行监测
     *
     * @param inputDto
     * @return
     * @author muhf
     * @date 2024/9/2 15:26
     */
    @PostMapping("getOperationMonitorByMonth")
    public ResultData getOperationMonitorByMonth(@RequestBody CockpitStatisticalAnalysisInputDto inputDto) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 设置最大最小日期范围（可按需调整）
        Date minDate = sdf.parse("2021-01-01 00:00:00");
        Date maxDate = sdf.parse("2025-12-31 23:59:59");

        // 获取时间戳（毫秒）
        long minTime = minDate.getTime();
        long maxTime = maxDate.getTime();

        // 创建 Random 实例
        Random random = new Random();

        // 随机生成开始时间
        long startTime = minTime + (long) (random.nextDouble() * (maxTime - minTime));
        Date startDate = new Date(startTime);

        long maxDuration = 1000L * 60 * 60 * 24 * 30; // 30天的毫秒数
        // 限制最多 30 天内
        if (StringUtils.equalsIgnoreCase(inputDto.getType(), "30")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "60")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "90")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "180")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "270")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "180")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "365")) {
            maxDuration =  1000L * 60 * 60 * 24 * Integer.parseInt(inputDto.getType());
        }

        long endTime = startTime + (long) (random.nextDouble() * maxDuration);

        // 不能超过全局最大时间
        if (endTime > maxDate.getTime()) {
            endTime = maxDate.getTime();
        }

        Date endDate = new Date(endTime);


        // 随机生成 heatUnitId（10001 ~ 13000）
        int min = 10001;
        int max = 13000;
        // heat_net_id  随机吧 10001-13000
        String heatUnitId = String.valueOf(new Random().nextInt(max - min + 1) + min);
        System.out.println("查询条件：heatUnitId,startDate,endDate," + heatUnitId + "," + startDate + "," + endDate);
        List<String> heatUnitIdList = new ArrayList<>();
        heatUnitIdList = Arrays.asList(heatUnitId.split(","));
        List<ScadaHistory> scadaHistories = scadaHisthoyMapper.getUnitHistoryDataList(heatUnitIdList, startDate, endDate, "100000000");

        ResultData result = new ResultData();
        result.setStartDate(startDate);
        result.setEndDate(endDate);
        result.setHeatUnitId(heatUnitId);
        result.setData(scadaHistories);
        result.setTotal(scadaHistories.size());
        return result;
    }

    /**
     * 运行监测
     *
     * @param inputDto
     * @return
     * @author muhf
     * @date 2024/9/2 15:26
     */
    @PostMapping("getOperationMonitorFixMonth")
    public ResultData getOperationMonitorFixMonth(@RequestBody CockpitStatisticalAnalysisInputDto inputDto) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        int minYear = 2022;
        int maxYear = 2023;
        int year = new Random().nextInt(maxYear - minYear + 1) + minYear;

        // 设置最大最小日期范围（可按需调整）
        String startDateStr = year + "-01-01 00:00:00";
        String endDateStr = year + "-02-01 00:00:00";

        Date minDate = sdf.parse(startDateStr);
        Date maxDate = sdf.parse(endDateStr);

        if (StringUtils.equalsIgnoreCase(inputDto.getType(), "30")) {
            endDateStr = year + "-02-01 00:00:00";
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "60")) {
            endDateStr = year + "-03-01 00:00:00";
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "90")) {
            endDateStr = year + "-04-01 00:00:00";
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "180")) {
            endDateStr = year + "-07-01 00:00:00";
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "270")) {
            endDateStr = year + "-10-01 00:00:00";
        } else if (StringUtils.equalsIgnoreCase(inputDto.getType(), "365")) {
            endDateStr = (year + 1) + "-01-01 00:00:00";
        }

        maxDate = sdf.parse(endDateStr);
        int unitCount = 10;
        if (inputDto.getUnitCount() != null) {
            unitCount = Integer.parseInt(inputDto.getUnitCount());
        }
        List<String> heatUnitIdList = new ArrayList<>();
        for (int i = 0; i < unitCount; i++) {
            int min = 10001;
            int max = 13000;
            String heatUnitId = String.valueOf(new Random().nextInt(max - min + 1) + min);
            heatUnitIdList.add(heatUnitId);
        }

//        heatUnitIdList = Arrays.asList(inputDto.getHeatUnitId().split(","));
        System.out.println("查询条件：heatUnitId,startDate,endDate," + JSONUtils.toJSONString(heatUnitIdList) + "," + minDate + "," + maxDate);
        List<ScadaHistory> scadaHistories = scadaHisthoyMapper.getUnitHistoryDataList(heatUnitIdList, minDate, maxDate, inputDto.getCnt());

        ResultData result = new ResultData();
        result.setStartDate(minDate);
        result.setEndDate(maxDate);
        result.setHeatUnitId(JSONUtils.toJSONString(heatUnitIdList));
        result.setData(scadaHistories);
        result.setTotal(scadaHistories.size());
        return result;
    }

    /**
     * @param inputDto
     * @return Result
     * @description 查询历史数据列表
     * @author wangmingwei
     * @date 2024年4月19日10:17:29
     */
    @PostMapping("getHistoryDataList")
    public ResultData getHistoryDataList(@RequestBody HistoryDataSearchInputDto inputDto) throws ParseException {

// 获取动态参数设置
        List<Map<String, String>> dynamicParameter = historyDataDao.getDynamicParameter();

        // 需要查询的数据库表名
        String tableName = "scada_history";
        // 汇总方式开始
        String summaryMethod = "";
        // 汇总方式结尾
        String summaryMethodEnd = "";
        // 统计方式
        String statisticalMethods = "";
        // 分组方式
        String groupBy = "";
        // 判断汇总方式，获取历史数据所有字段

        // 随机设置汇总方式（表名） summaryMethod 为 0, 1, 或 2
        Random random = new Random();
        int[] summaryMethods = {0, 1, 2};
        inputDto.setSummaryMethod(summaryMethods[random.nextInt(summaryMethods.length)]);
        // TODO
        inputDto.setSummaryMethod(2);

//        // 随机设置统计方式 statisticalMethods 为 "0", "1", 或 "2"
//        Random randomstatisticalMethods = new Random();
//        String[] statisticalMethodsArray = {"0", "1", "2"};
//        inputDto.setStatisticalMethods(statisticalMethodsArray[randomstatisticalMethods.nextInt(statisticalMethodsArray.length)]);

        int unitCount = 10;
        if (inputDto.getUnitCount() != null) {
            unitCount = Integer.parseInt(inputDto.getUnitCount());
        }
        List<Long> heatUnitIdList = new ArrayList<>();
        int min = 10001;
        int max = 13000;
        Set<Long> generatedIds = new HashSet<>(); // 用于去重
        while (heatUnitIdList.size() < unitCount) {
            int randomNum = new Random().nextInt(max - min + 1) + min;
            Long heatUnitId = (long) randomNum;

            if (generatedIds.add(heatUnitId)) { // 只有不重复才添加
                heatUnitIdList.add(heatUnitId);
            }
        }
        inputDto.setUnitIds(heatUnitIdList);

        // 平均值
        if (0 == (ObjectUtils.isEmpty(inputDto.getSummaryMethod()) ? 4 : inputDto.getSummaryMethod())) {
            // 查询平均数表
            tableName = "scada_history_mean";
            // 平均数方法
            summaryMethod = "round(avg(";
            // 平均数结尾
            summaryMethodEnd = "),2)";
            // 最大值
        } else if (1 == (ObjectUtils.isEmpty(inputDto.getSummaryMethod()) ? 4 : inputDto.getSummaryMethod())) {
            // 查询最大数表
            tableName = "scada_history_max";
            // 最大数方法
            summaryMethod = "max(";
            // 最大数结尾
            summaryMethodEnd = ")";
            // 最小值
        } else if (2 == (ObjectUtils.isEmpty(inputDto.getSummaryMethod()) ? 4 : inputDto.getSummaryMethod())) {
            // 查询最小数表
            tableName = "scada_history_min";
            // 最小数方法
            summaryMethod = "min(";
            // 最小数结尾
            summaryMethodEnd = ")";
        }


        // 如果是小时汇总
        if ("0".equals(inputDto.getStatisticalMethods())) {
            // 查询时间格式化字段(小时)
            statisticalMethods = "date_format(data_time, '%Y-%m-%d %H') date,";
            // 按小时分组
            groupBy = "date";
            // 如果是按天汇总
        } else if ("1".equals(inputDto.getStatisticalMethods())) {
            // 查询时间格式化字段(天)
            statisticalMethods = "date_format(data_time, '%Y-%m-%d') date,";
            // 按天分组
            groupBy = "date";
            // 如果是按月汇总
        } else if ("2".equals(inputDto.getStatisticalMethods())) {
            // 查询时间格式化字段(月)
            statisticalMethods = "date_format(data_time, '%Y-%m') date,";
            // 按月分组
            groupBy = "date";
            // 如果是明细，则没有汇总方式
        } else {
            // 查询时间格式化字段(明细)
            statisticalMethods = "data_time as date,";
            // 重置汇总方式开始
            summaryMethod = "";
            // 重置汇总方式结束
            summaryMethodEnd = "";
            // 重置数据库表名
            tableName = "scada_history";
        }


        // 查询对应历史表中的所有字段名称
        List<Map<String, String>> histroydynamicParameter = historyDataDao.getHistoryParameter(tableName + "_01");
        // 动态参数列表与历史数据字段列表取交集
        List<Map<String, String>> parameterList = dynamicParameter.stream().filter(histroydynamicParameter::contains).collect(Collectors.toList());
        // 将每个map的values流连接起来
        List<String> collect = parameterList.stream().flatMap(map -> map.values().stream()).collect(Collectors.toList());
        // 需要查询的字段
        String selectValue = ",";
        for (String columnName : collect) {
            selectValue += summaryMethod + columnName + summaryMethodEnd + " as " + columnName + ",";
        }
        // 查询信息
        List<Map<String, String>> historyDataList = new ArrayList<>();

        if (StringUtils.equalsIgnoreCase("YH", inputDto.getFlag())) {
            inputDto.setDataStartTime(inputDto.getDataStartTime() + ":00:00");
            inputDto.setDataEndTime(inputDto.getDataEndTime() + ":59:59");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date minDate = sdf.parse(inputDto.getDataStartTime());
            Date maxDate = sdf.parse(inputDto.getDataEndTime());
            historyDataList = historyDataDao.getHistoryDataListYH(minDate, maxDate, tableName,
                    selectValue, statisticalMethods, groupBy, inputDto);
        } else {
            historyDataList = historyDataDao.getHistoryDataList(tableName,
                    selectValue, statisticalMethods, groupBy, inputDto);
        }


        ResultData result = new ResultData();
        result.setData(historyDataList);
        result.setTotal(historyDataList.size());
        return result;
    }

    /**
     * @param inputDto
     * @return Result
     * @description 查询历史数据列表
     * @author wangmingwei
     * @date 2024年4月19日10:17:29
     */
    @PostMapping("getScadaHistoryMin")
    public ResultData getScadaHistoryMin(@RequestBody HistoryDataSearchInputDto inputDto) throws ParseException {

        int unitCount = 10;
        if (inputDto.getUnitCount() != null) {
            unitCount = Integer.parseInt(inputDto.getUnitCount());
        }
        List<Long> heatUnitIdList = new ArrayList<>();
        int min = 10001;
        int max = 13000;
        Set<Long> generatedIds = new HashSet<>(); // 用于去重
        while (heatUnitIdList.size() < unitCount) {
            int randomNum = new Random().nextInt(max - min + 1) + min;
            Long heatUnitId = (long) randomNum;

            if (generatedIds.add(heatUnitId)) { // 只有不重复才添加
                heatUnitIdList.add(heatUnitId);
            }
        }
        inputDto.setUnitIds(heatUnitIdList);

        // 查询信息
        List<Map<String, String>> historyDataList = new ArrayList<>();


        inputDto.setDataStartTime(inputDto.getDataStartTime() + ":00:00");
        inputDto.setDataEndTime(inputDto.getDataEndTime() + ":59:59");

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date minDate = sdf.parse(inputDto.getDataStartTime());
        Date maxDate = sdf.parse(inputDto.getDataEndTime());
        historyDataList = historyDataDao.getScadaHistoryMin(minDate, maxDate, "scada_history_min", "date", inputDto);


        ResultData result = new ResultData();
        result.setData(historyDataList);
        result.setTotal(historyDataList.size());
        return result;
    }

    /**
     * @param energyConsumptionInquiryDeptSearchInputDto
     * @return Result
     * @author wangmingwei
     * @Date 2024年7月15日13:11:28
     * @description 机组能耗查询
     */
    @PostMapping("getEnergyConsumptionInquiryUnitList")
    public ResultData getEnergyConsumptionInquiryUnitList(@RequestBody EnergyConsumptionInquiryDeptSearchInputDto energyConsumptionInquiryDeptSearchInputDto, HttpServletResponse response) {

        // 时间维度
        String statisticalMethods = "";

        // 时间维度
        String statisticalBy = "";

        // 分组方式
        String groupBy = "";
        // 查询时间格式化字段(小时)
        statisticalMethods = "date_format(data_time, '%Y-%m-%d %H') date,";
        statisticalBy = "date_format(data_time, '%Y-%m-%d %H')";
        // 按小时分组
        groupBy = "date";

        // 时间维度是日
        if (energyConsumptionInquiryDeptSearchInputDto.getTimeDimension() == 0) {
            statisticalMethods = "date_format(data_time, '%Y-%m-%d') date,";
            statisticalBy = "date_format(data_time, '%Y-%m-%d')";

            groupBy = "date";
            // 时间维度是月
        } else if (energyConsumptionInquiryDeptSearchInputDto.getTimeDimension() == 1) {
            statisticalMethods = "date_format(data_time, '%Y-%m') date,";
            statisticalBy = "date_format(data_time, '%Y-%m') ";

            groupBy = "date";
            // 时间维度是年
        } else if (energyConsumptionInquiryDeptSearchInputDto.getTimeDimension() == 2) {
            statisticalMethods = "date_format(data_time, '%Y') date,";
            statisticalBy = "date_format(data_time, '%Y') ";
            groupBy = "date";
        }
        // 查询列表
        List<EnergyConsumptionInquiryDeptSearchOutputDto> list = energyConsumptionInquiryDao.getEnergyConsumptionInquiryUnitList(
                energyConsumptionInquiryDeptSearchInputDto,
                statisticalMethods,
                statisticalBy,
                groupBy);

        ResultData result = new ResultData();
        result.setData(list);
        result.setTotal(list.size());
        return result;
    }
}
